{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### np.transpose 的手动实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.arange(6).reshape(2,3)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = np.zeros(a.shape[::-1], dtype=a.dtype)\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 填充值\n",
    "b[:,0] = a[0,:]\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b[:,1] = a[1,:]\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.all(a.T == b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### np.transpose 的手动实现（多维）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.arange(24).reshape(2,2,2,3)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = np.zeros(a.shape[::-1], dtype=a.dtype)\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.shape, b.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 一个可以对任意阵列做转置操作的函数\n",
    "#\n",
    "# 要点：\n",
    "# \n",
    "# 1. 创建一个新的阵列，此阵列的形状与原阵列完全颠倒\n",
    "# 2. 循环取出原阵列中倒数第二个维里面所有的元素（每一个元素就是一个一维数组）\n",
    "# 3. 把取出来的一维数组赋值给新阵列颠倒的位置，即 b[:,0,1,2] <---> a[2,1,0,:]\n",
    "# 4. 利用np.ndindex方便地生成多个索引值\n",
    "# 5. 如何表示冒号的索引？ slice(None)\n",
    "# 6. 如果原阵列只有一维，如何处理？\n",
    "\n",
    "def transpose(a):\n",
    "    b = np.zeros(a.shape[::-1], dtype=a.dtype)\n",
    "    for index in np.ndindex(a.shape):\n",
    "        b[index[::-1]] = a[index]\n",
    "    return b\n",
    "\n",
    "\n",
    "def transpose2(a):\n",
    "    b = np.zeros(a.shape[::-1], dtype=a.dtype)\n",
    "    for index in np.ndindex(a.shape[:-1]):\n",
    "        index = index + (slice(None),)\n",
    "        b[index[::-1]] = a[index]\n",
    "    return b\n",
    "\n",
    "\n",
    "a = np.ones((2,3,4,100))\n",
    "%timeit transpose(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%timeit transpose2(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.random.randint(-10, 10, 30)\n",
    "\n",
    "# 取出a中大于零的元素\n",
    "a[np.where(a>0)]\n",
    "a[np.where(a<=0)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### a.ravel() 生成的阵列可能是浅副本，也有可能是深副本\n",
    "### a.flatten() 生成的阵列都是深副本\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
